/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package agentes;

import acoes.DadosAcao;


import acoes.InformacoesAcao;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author marapao
 */
public class Prospectador implements Agente {

    double reputacao;
    List<String> acoes;
    List<String> palpite;
    List<DadosAcao> historico;
    int criterio;
    String nome;
    InformacoesAcao inf;

    public InformacoesAcao getInf() {
        return inf;
    }

    public void setInf(InformacoesAcao inf) {
        this.inf = inf;
    }

    public List<String> getPalpite() {

        return palpite;
    }

    public void setPalpite(List<String> palpite) {
        this.palpite = palpite;
    }

    public Prospectador() {
        inf = new InformacoesAcao();
        historico = new ArrayList();
    }

    public void atualizaHistorico() {
        inf = new InformacoesAcao();
        for (String acao : acoes) {
            try {


                historico.add(
                        inf.buscaPorId(acao, historico));
            } catch (Exception ex) {
                System.out.println("Ação " + acao + " inválida.");
                Logger.getLogger(Prospectador.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    public void addHistorico(DadosAcao acao) {
        historico.add(acao);
    }

    public Prospectador(double reputacao, List<String> acoes, List<DadosAcao> historico, int criterio, String nome) {
        this.reputacao = reputacao;
        this.acoes = acoes;
        this.historico = historico;
        this.criterio = criterio;
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getCriterio() {
        return criterio;
    }

    public void setCriterio(int criterio) {
        this.criterio = criterio;
    }

    public List<DadosAcao> getHistorico() {
        return historico;
    }

    public void setHistorico(List<DadosAcao> historico) {
        this.historico = historico;
    }

    public List<String> getAcoes() {
        return acoes;
    }

    public void setAcoes(List<String> acoes) {
        this.acoes = acoes;
    }

    public double getReputacao() {
        return reputacao;
    }

    public void setReputacao(double reputacao) {
        this.reputacao = reputacao;
    }

    public void atualizaHistórico(DadosAcao dados) {
        historico.add(dados);
    }

    //retorna array ordenado de dias mais distantes(posição 0) e dias mais próximos(n-1)
    //com até n posições
    public DadosAcao[] ultimosValores(String cod, int n) {
        DadosAcao[] res = new DadosAcao[n];

        int tamanho = historico.size();
        DadosAcao dados;
        int j = n - 1;

        for (int i = tamanho - 1; i >= 0; i--) {
            dados = historico.get(i);
            if (dados.getCodigo().equals(cod) && j >= 0) {
                res[j--] = new DadosAcao(
                        dados.getDescricao(),
                        dados.getCodigo(),
                        dados.getIbovespa(),
                        dados.getDelay(),
                        dados.getData(),
                        dados.getOscilacao(),
                        dados.getUltimoValor(),
                        dados.getQuantiNeg(),
                        dados.getMercado());
            } else if (j < 0) {
                i = -1;
            }

        }

        return res;
    }

    //plano que o agente irá executar
    public List<String> plano() {

        List resposta = new LinkedList();

        DadosAcao[] dados = null;
        int n = 5;//numero de cotações anteriores que serão avaliadas
        int investe = 0, naoInveste = 0;
        double percentagem = 1.05;
        int naoNulo = 0;

        for (String acao : acoes) {
            naoNulo = 0;
            dados = ultimosValores(acao, n);

            for (DadosAcao dadosAcao : dados) {
                if(!dados.equals(null))
                    naoNulo++;
            }

            if(naoNulo < 2)
                continue;


            
            //ação subiu mais que caiu nos ultimos n casos
            if (criterio == 1) {
                for (int i = 0; i < dados.length - 2; i++) {

                    if(dados[i] == null || dados[i + 1] == null)
                        continue;

                    if (criterio1(dados[i], dados[i + 1])) {
                        investe++;
                    } else {
                        naoInveste++;
                    }
                }
            } //ação caiu mais que subiu nos ultimos n casos
            else if (criterio == 2) {
                for (int i = 0; i < dados.length - 2; i++) {

                    if(dados[i] == null || dados[i + 1] == null)
                        continue;

                    if (criterio1(dados[i], dados[i + 1])) {
                        naoInveste++;
                    } else {
                        investe++;
                    }
                }

            }//ação valorizou (percentagem  -1)
            else if (criterio == 3) {

                if (percentagem < criterio2(dados[0], dados[dados.length - 1])) {
                    investe++;
                } else {
                    naoInveste++;
                }
            } //ação desvalorizou
            else if (criterio == 4) {

                if (criterio2(dados[0], dados[dados.length - 1]) < 1) {
                    investe++;
                } else {
                    naoInveste++;
                }
            }


            //adiciona ação em caso positivo
            if (investe > naoInveste) {
                resposta.add(acao);
            }

            investe = 0;
            naoInveste = 0;
        }


        return resposta;
    }

    //critério que leva em consideração se o preço aumentou
    public boolean criterio1(DadosAcao primeiro, DadosAcao segundo) {

        if (Double.parseDouble(primeiro.getUltimoValor()) > Double.parseDouble(segundo.getUltimoValor())) {
            return true;
        } else {
            return false;
        }

    }

    //retorna a percentagem de queda ou aumento
    public double criterio2(DadosAcao primeiro, DadosAcao ultimo) {

        return (Double.parseDouble(primeiro.getUltimoValor()) / Double.parseDouble(ultimo.getUltimoValor()));

    }

    public void calculaPalpite() {
        setPalpite(plano());
    }
}
